package com.person.yhzs.wxPaySDK.util;

import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.springframework.util.Base64Utils;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author luolin
 * @Description 支付工具类
 * @createTime 2022年06月24日 11:08:00
 */
public class PayUtil {

    /**
     * @Description 向指定URL发送GET方法的请求，请求参数格式为：name1=value1&name2=value2
     * @Author luolin
     * @Date 2022/6/24 11:32
     **/
    public static String sendGet(String url,String param){
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            System.out.println(urlNameString);
            URL realurl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realurl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept","*/*");
            connection.setRequestProperty("connection","Keep-Alive");
            connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            //建立实际的连接
            connection.connect();

            // 获取所有的响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key: map.keySet()) {
                System.out.println(key + "===>" + map.get(key));
            }
            // 定义BufferReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null){
                result += line;
            }
        }catch (Exception e){
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }finally{
            try {
                if(in != null){
                    in.close();
                }
            }catch (Exception e2){
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * @Description 向指定URL发送 POST 方法的请求，请求参数格式为：name1=value1&name2=value2
     * @Author luolin
     * @Date 2022/6/24 11:32
     **/
    public static String sendPost(String url,String param){
        PrintWriter out = null;
        String result = "";
        BufferedReader in = null;
        try {
//            String urlNameString = url + "?" + param;
//            System.out.println(urlNameString);
            URL realurl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = realurl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept","*/*");
            connection.setRequestProperty("connection","Keep-Alive");
            connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送PSOT请求必须设置如下两行
            connection.setDoOutput(true);
            connection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(connection.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
            String line;
            while ((line = in.readLine()) != null){
                result += line;
            }

            //建立实际的连接
//            connection.connect();
//
//            // 获取所有的响应头字段
//            Map<String, List<String>> map = connection.getHeaderFields();
//            // 遍历所有的响应头字段
//            for (String key: map.keySet()) {
//                System.out.println(key + "===>" + map.get(key));
//            }
//            // 定义BufferReader输入流来读取URL的响应
//            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//            String line;
//            while ((line = in.readLine()) != null){
//                result += line;
//            }
        }catch (Exception e){
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }finally{
            try {
                if(out != null){
                    out.close();
                }
                if(in != null){
                    in.close();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String httpsRequest(String requestUrl, String requestMethod, String output){
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            if (null != output){
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes(StandardCharsets.UTF_8));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer stringBuffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null){
                stringBuffer.append(str);
            }
            bufferedReader.close();
            inputStream.close();
            inputStreamReader.close();
            inputStream = null;
            connection.disconnect();
            return bufferedReader.toString();

        }catch (Exception e){
            e.printStackTrace();
        }finally{

        }
        return "";
    }

    /**
     * 加密算法提供方 - BouncyCastle
     */
    private static final String BC_PROVIDER = "BC";

    /**
     * 请求时设置签名   组件
     * @param components the components
     * @return string string
     */
    private static String createSign(boolean newLine, String... components) {
        String suffix = newLine ? "\n" : "";
        return Arrays.stream(components).collect(Collectors.joining("\n", "", suffix));
    }

    /**
     *
     * @param privateKey
     * @param orderedComponents
     * @return
     */
    public static String doRequestSign(String privateKey, String... orderedComponents) {
        try {
            // 商户私钥
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
            Signature signer = Signature.getInstance("SHA256withRSA");
            signer.initSign(merchantPrivateKey);
            final String signatureStr = createSign(true, orderedComponents);
            signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
            return Base64Utils.encodeToString(signer.sign());
        } catch (InvalidKeyException e) {
//            log.error("InvalidKeyException: {}", e);
            e.printStackTrace();
        } catch (SignatureException e) {
//            log.error("SignatureException: {}", e);
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
//            log.error("NoSuchAlgorithmException: {}", e);
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
//            log.error("UnsupportedEncodingException: {}", e);
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 使用微信平台证书，对微信回调数据验签，做应答签名比较
     * @param certificate
     * @param wechatpaySignature
     * @param wechatpayTimestamp
     * @param wechatpayNonce
     * @param body
     * @return
     */
    public static boolean responseSignVerify(String certificate, String wechatpaySignature, String wechatpayTimestamp, String wechatpayNonce, String body) {
        try {
            final String signatureStr = createSign(true, wechatpayTimestamp, wechatpayNonce, body);
            Signature signer = Signature.getInstance("SHA256withRSA");
            signer.initVerify(PemUtil.loadCertificate(new ByteArrayInputStream(certificate.getBytes("utf-8"))));
            signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
            // ...
            return signer.verify(Base64Utils.decodeFromString(wechatpaySignature));
        } catch (UnsupportedEncodingException e) {
//            log.error("UnsupportedEncodingException: {}", e);
        } catch (SignatureException e) {
//            log.error("SignatureException: {}", e);
        } catch (NoSuchAlgorithmException e) {
//            log.error("NoSuchAlgorithmException: {}", e);
        } catch (InvalidKeyException e) {
//            log.error("InvalidKeyException: {}", e);
        }
        return false;
    }

    /**
     * 字符串
     * @return
     */
    public static String CreateNoncestr() {
        String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        String res = "";
        for (int i = 0; i < 16; i++) {
            Random rd = new Random();
            res += chars.charAt(rd.nextInt(chars.length() - 1));
        }
        return res;
    }

    /**
     * 得到时间戳
     * @return
     */
    public static String getTimestamp() {
        long epochSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        return String.valueOf(epochSecond);
//		return Long.toString(System.currentTimeMillis() / 1000);
    }
}
